# coding:utf-8
import sys_utils
import tap_config

class VSCTLHandler(object):

    '''
    ACTION_TYPE字段解析：
    * 1. 获取所有物理端口信息
    * 2. 设置物理端口状态
    * 3. 获取所有LAG端口信息
    * 4. 设置LAG端口信息
    * 5. 获取所有逻辑组信息
    * 6. 设置逻辑组信息
    * 7. 设置控制器
    '''
    def __init__(self, data_container):
        self.data_container = data_container

    # 获取交换机所有物理端口的信息（类型1）
    def fetch_phyports_info(self, params):
        rets = {}
        ports = []
        for port in self.data_container.get_phyports():
            port_info = {}
            port_info['phy_port_id'] = port.port_id
            port_info['phy_port_name'] = port.port_name
            port_info['phy_port_alias'] = port.port_alias
            port_info['phy_tap_flag'] = port.tap_flag
            ports.append(port_info)

        rets['phy_ports'] = ports
        rets['return'] = True
        return rets

    # 设置物理端口状态（类型2）
    def set_phyport_info(self, params):
        rets = {}
        id = int(params['phy_port_id'])
        alias = params['phy_port_alias']
        tap = params['phy_tap_flag']

        target_port = self.data_container.get_phyport(id)
        if target_port == None:
            rets['return'] = False
            rets['error'] = 'No such port in database'
            return rets

        self.data_container.set_phyport_alias(id, alias)
        self.data_container.set_phyport_tap(id, tap)
        rets['return'] = True
        return rets

    # 获取所有LAG端口信息（类型3）
    def fetch_lagports_info(self, params):
        rets = {}
        ports = []
        for port in self.data_container.get_lagports():
            port_info = {}
            port_info['lag_port_id'] = port.port_id
            port_info['lag_port_name'] = port.port_name
            port_info['lag_port_alias'] = port.port_alias
            port_info['include_ports'] = port.include_ports
            ports.append(port_info)

        rets['lag_ports'] = ports
        rets['return'] = True
        return rets

    # 生成设置LAG端口的命令（类型4）
    def set_lagport_process(self, params):
        rets = {}
        inputs = {}
        inputs['vsctl'] = tap_config.vsctl
        inputs['br_name'] = tap_config.bridge_name

        # 获取请求内容信息
        id = int(params.get('lag_port_id'))
        alias = params.get('lag_port_alias')
        include_ports = params.get('include_ports')

        for i in range(len(include_ports)):
            include_ports[i] = int(include_ports[i])

        # 生成对应包含端口的字符串信息
        names = []
        for port_id in include_ports:
            name = self.data_container.get_phyport(port_id).port_name
            names.append(name)
        include_ports_str = ','.join(names)

        target_lagport = self.data_container.get_lagport(id)

        # 不存在对应LAG端口，则执行添加操作
        if not target_lagport:
            # add lagport
            op_type = 1
            lag_port_name = 'ae' + str(id)
            inputs['lagport_name'] = lag_port_name
            inputs['include_ports'] = include_ports_str
            retcmd = tap_config.ADD_LAG_PORT_CMD.substitute(inputs)
        else:
            lag_port_name = target_lagport.port_name
            if include_ports_str == '':
                # delete lagport
                op_type = 2
                inputs['lagport_name'] = lag_port_name
                retcmd = tap_config.DEL_LAG_PORT_CMD.substitute(inputs)
            else:
                # modify lagport
                op_type = 3
                inputs['lagport_name'] = lag_port_name
                inputs['include_ports'] = include_ports_str
                retcmd = tap_config.MOD_LAG_PORT_CMD.substitute(inputs)

        # status: 0->success + -1->failure || result -> 返回结果 || error -> 返回错误
        status, result, error = sys_utils.execute_cmd_line(retcmd)

        # todo: 执行LAG口添加，一直报错'ovs-vsctl: Error detected while setting up 'ae2023'.  See ovs-vswitchd log for details.'
        # todo: 但实际上却能添加成功，能够通过'ovs-vsctl show'查看到添加的端口，因此，在此处，我们认为添加成功
        # todo: 因此，我们将下面的代码贴在错误判断前（应该进行修改的！！！）
        if op_type == 1:
            # 新增操作
            self.data_container.add_lagport(id, lag_port_name, alias)
            self.data_container.set_lagport_inports(id, include_ports)
        elif op_type == 2:
            # 删除操作
            self.data_container.del_lagport(id)
        elif op_type == 3:
            # 修改操作
            self.data_container.set_lagport_alias(id, alias)
            self.data_container.set_lagport_inports(id, include_ports)

        # todo: 下述代码段应该置于前面的todo代码段之前
        if status == -1:
            rets['return'] = False
            rets['error'] = error
            return rets

        rets['return'] = True

        return rets

    # 获取所有逻辑组信息（类型5）
    def fetch_logicgroups_info(self, params):
        rets = {}
        groups = []
        for group in self.data_container.get_logicgroups():
            group_info = {}
            group_info['logic_group_id'] = group.lg_id
            group_info['logic_group_name'] = group.lg_name
            group_info['logic_group_alias'] = group.lg_alias
            group_info['include_ports'] = group.include_ports
            groups.append(group_info)

        rets['logic_groups'] = groups
        rets['return'] = True
        return rets

    # 设置逻辑组信息（类型6）
    def set_logicgroup_info(self, params):
        id = int(params.get('logic_group_id'))
        alias = params.get('logic_group_alias')
        include_ports = params.get('include_ports')

        for i in range(len(include_ports)):
            include_ports[i] = int(include_ports[i])

        target_logicgroup = self.data_container.get_logicgroup(id)

        # 不存在对应LAG端口，则执行添加操作
        if not target_logicgroup:
            name = "lgroup" + str(id)
            self.data_container.add_logicgroup(id, name, alias)
            self.data_container.set_logicgroup_inports(id, include_ports)
        else:
            if len(include_ports) == 0:
                # delete lagport
                self.data_container.del_logicgroup(id)
            else:
                # modify lagport
                self.data_container.set_logicgroup_alias(id, alias)
                self.data_container.set_logicgroup_inports(id, include_ports)

    # 设置控制器（类型7）
    def set_controller_process(self, params):
        rets = {}
        inputs = {}
        inputs['vsctl'] = tap_config.vsctl
        inputs['br_name'] = tap_config.bridge_name

        ctrl_name = params.get('controller_name')
        ctrl_ip = params.get('controller_ip')
        ctrl_port = params.get('controller_port')
        self.data_container.set_controller(ctrl_name, ctrl_ip, ctrl_port)

        inputs['controller_ip'] = ctrl_ip
        inputs['controller_port'] = ctrl_port
        retcmd = tap_config.SET_CONTROLLER_CMD.substitute(inputs)

        print retcmd
        # status: 0->success + -1->failure || result -> 返回结果 || error -> 返回错误
        status, result, error = sys_utils.execute_cmd_line(retcmd)

        if status == -1:
            rets['return'] = False
            rets['error'] = error
            return rets

        rets['return'] = True
        return rets

    def handle_event(self, params):
        '''
        核心处理函数
        '''
        retinfo = {}
        type = params['action_type']
        if type == 1:
            # 获取所有物理端口信息
            retinfo = self.fetch_phyports_info(params)
        elif type == 2:
            # 设置指定物理端口状态
            retinfo = self.set_phyport_info(params)
        elif type == 3:
            # 获取所有LAG端口信息
            retinfo = self.fetch_lagports_info(params)
        elif type == 4:
            # 设置LAG端口信息（包括增、删、改LAG端口）
            retinfo = self.set_lagport_process(params)
        elif type == 5:
            # 获取所有逻辑组信息
            retinfo = self.fetch_logicgroups_info(params)
        elif type == 6:
            # 配置逻辑组信息（包括增、删、改逻辑组）
            retinfo = self.set_logicgroup_info(params)
        elif type == 7:
            # 设置控制器信息
            retinfo = self.set_controller_process(params)

        return retinfo